<?php
namespace App\Common\Lib\Fun;

use App\Common as com;

class Location {
	/**
	 * 获取客户端ip地址
	 * @param num $type 获取类型 [0][默认]IP地址段 [1]整型型ip地址
	 * @return NULL|string|numeric|NULL|unknown [null]获取错误
	 */
	public static function getClientIp( $type = 0 ){
		$type = $type ? 1 : 0;
		static $ip = NULL;
		if( $ip !== NULL ) return $ip[ $type ];
		if( isset( $_SERVER['HTTP_X_REAL_IP'] ) ){ // nginx 代理模式下，获取客户端真实IP
			$ip = $_SERVER['HTTP_X_REAL_IP'];
		}elseif( isset( $_SERVER['HTTP_CLIENT_IP'] ) ){ // 客户端的ip
			$ip = $_SERVER['HTTP_CLIENT_IP'];
		}elseif( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ){ // 浏览当前页面的用户计算机的网关
			$arr = explode( ',', $_SERVER['HTTP_X_FORWARDED_FOR'] );
			$pos = array_search( 'unknown', $arr );
			if( false !== $pos ) unset( $arr[$pos] );
			$ip = trim( $arr[0] );
		}elseif( isset( $_SERVER['REMOTE_ADDR'] ) ){
			$ip = $_SERVER['REMOTE_ADDR']; // 浏览当前页面的用户计算机的ip地址
		}else{
			return null;
		}
		// IP地址合法验证
		$long = sprintf( "%u", ip2long( $ip ) );
		$ip = $long ? array( $ip, $long ) : array( '0.0.0.0', 0 );
		return $ip[ $type ];
	}
	
	/**
	 * 服务器IP地址
	 */
	public static function getServerIp(){    
		if( isset( $_SERVER ) ){
			if( $_SERVER['SERVER_ADDR'] ?? null ){
				$server_ip = $_SERVER['SERVER_ADDR'];
			}else{    
				$server_ip = $_SERVER['LOCAL_ADDR'] ?? '';
			}
		}else{
			$server_ip = getenv('SERVER_ADDR');
		}
		return $server_ip;    
	}    
  
	/**
	 * 坐标转换到腾讯坐标（腾讯地图 WEB_API）(单条)
	 * 参考：http://lbs.qq.com/webservice_v1/guide-convert.html
	 * @param str $lng 纬度
	 * @param str $lat 经度
	 * @param int $type 原坐标类型,可选值为[1,6]之间的整数，每个数字代表的类型说明： 
	 *			1 GPS坐标
	 *			2 sogou经纬度
	 * 			3 baidu经纬度
	 * 			4 mapbar经纬度
	 * 			5 [默认]腾讯、google、高德坐标
	 * 			6 sogou墨卡托
	 * @return array||null [null]转换失败 [array]转换成功，格式：[ 'lng' => '', 'lat' => '' ]
	 */
	public static function locationsTranslateOneOfTX( $lng, $lat, $type = 1 ){
		$api_url = "http://apis.map.qq.com/ws/coord/v1/translate?locations={$lat},{$lng}&type={$type}&key=2JDBZ-ZSLKF-CQGJH-N5ONA-ECRIS-3KFR5";
		$json_data = file_get_contents( $api_url );
		$data = json_decode($json_data, true );
		if( ! isset( $data['status'] ) ) return null;
		if( ! isset( $data['locations'] ) ) return null;
		if( $data['status'] == 0 ){
			return [
				'lng' => $data['locations'][0]['lng'],
				'lat' => $data['locations'][0]['lat'],
			];
		}
		return null;
	}
	
	/**
	 * 坐标转换到腾讯坐标（腾讯地图 WEB_API）(单条)
	 * 参考：http://lbsyun.baidu.com/index.php?title=webapi/guide/changeposition
	 * @param str $lng 纬度
	 * @param str $lat 经度
	 * @param array $param 参数数组 <br />
	 * ················· [可空](int)	$param['from']	说明：源坐标类型。[默认][1]	<br />
	 * 		1：GPS设备获取的角度坐标，wgs84坐标;
	 * 		2：GPS获取的米制坐标、sogou地图所用坐标;
	 * 		3：google地图、soso地图、aliyun地图、mapabc地图和amap地图所用坐标，国测局（gcj02）坐标;
	 * 		4：3中列表地图坐标对应的米制坐标;
	 * 		5：百度地图采用的经纬度坐标;
	 * 		6：百度地图采用的米制坐标;
	 * 		7：mapbar地图坐标;
	 *		8：51地图坐标
	 * ················· [可空](int)	$param['to']	说明：目标坐标类型。[默认][5]	<br />
	 * 		3：国测局（gcj02）坐标;
	 * 		4：3中对应的米制坐标;
	 * 		5：bd09ll(百度经纬度坐标);
	 * 		6：bd09mc(百度米制经纬度坐标)
	 * ················· [可空/多选_A/必须](unknown_type)	$param['AAAAA']	说明：AAAAA	<br />
	 * @return array||null [null]转换失败 [array]转换成功，格式：[ 'lng' => '', 'lat' => '' ]
	 */
	public static function locationsTranslateOneToBd( $lng, $lat, array $param = [] ){
		// ...
		$param['from'] = $param['from'] ?? 1;
		$param['to'] = $param['to'] ?? 5;
		//
		$api_url = "http://api.map.baidu.com/geoconv/v1/?coords={$lng},{$lat}&from={$param['from']}&to={$param['to']}&ak=FccI5fwZvVoek54FK6auDonES1kAXMK4";
		$json_data = file_get_contents( $api_url );
		$data = json_decode($json_data, true );
		if( ! isset( $data['status'] ) ) return null;
		if( ! isset( $data['result'] ) ) return null;
		if( $data['status'] == 0 ){
			return [
				'lng' => $data['result'][0]['x'],
				'lat' => $data['result'][0]['y'],
			];
		}
		return null;
	}
	
	/**
	 * 经伟度计算距离
	 * @param unknown $fP1Lat
	 * @param unknown $fP1Lon
	 * @param unknown $fP2Lat
	 * @param unknown $fP2Lon
	 * @return number
	 */
	public static function distanceBetween($fP1Lat, $fP1Lon, $fP2Lat, $fP2Lon){
	    $fEARTH_RADIUS = 6378137;
	    //角度换算成弧度
	    $fRadLon1 = deg2rad($fP1Lon);
	    $fRadLon2 = deg2rad($fP2Lon);
	    $fRadLat1 = deg2rad($fP1Lat);
	    $fRadLat2 = deg2rad($fP2Lat);
	    //计算经纬度的差值
	    $fD1 = abs($fRadLat1 - $fRadLat2);
	    $fD2 = abs($fRadLon1 - $fRadLon2);
	    //距离计算
	    $fP = pow(sin($fD1/2), 2) + cos($fRadLat1) * cos($fRadLat2) * pow(sin($fD2/2), 2);
	    return intval($fEARTH_RADIUS * 2 * asin(sqrt($fP)) + 0.5);
	}
	
	
	/**
	 * 方法二
	 * @param unknown $longitude1
	 * @param unknown $latitude1
	 * @param unknown $longitude2
	 * @param unknown $latitude2
	 * @param number $unit
	 * @param number $decimal
	 * @return number
	 */
	public static function getDistance($longitude1, $latitude1, $longitude2, $latitude2, $unit=2, $decimal=2){
	    
	    $EARTH_RADIUS = 6370.996; // 地球半径系数
	    $PI = 3.1415926;
	    
	    $radLat1 = $latitude1 * $PI / 180.0;
	    $radLat2 = $latitude2 * $PI / 180.0;
	    
	    $radLng1 = $longitude1 * $PI / 180.0;
	    $radLng2 = $longitude2 * $PI /180.0;
	    
	    $a = $radLat1 - $radLat2;
	    $b = $radLng1 - $radLng2;
	    
	    $distance = 2 * asin(sqrt(pow(sin($a/2),2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2),2)));
	    $distance = $distance * $EARTH_RADIUS * 1000;
	    
	    if($unit==2){
	        $distance = $distance / 1000;
	    }
	    
	    return round($distance, $decimal);
	    
	}
	
	/**
	 * WGS-84：是国际标准，GPS坐标（Google Earth使用、或者GPS模块）
        GCJ-02：中国坐标偏移标准，Google Map、高德、腾讯使用
        BD-09：百度坐标偏移标准，Baidu Map使用
	 * 坐标转换
	 * //GCJ-02 to BD-09 
	 */
	public static function bd_encrypt($gcjLat, $gcjLon) {
	    $PI = 3.14159265358979324;
	    $x_pi = 0;
	    $x_pi = 3.14159265358979324 * 3000.0 / 180.0;
	    $x = $gcjLon; $y = $gcjLat;
	    $z = sqrt($x * $x + $y * $y) + 0.00002 * sin($y * $x_pi);
	    $theta = atan2($y, $x) + 0.000003 * cos($x * $x_pi);
	    $bdLon = $z * cos($theta) + 0.0065;
	    $bdLat = $z * sin($theta) + 0.006;
	    return array('lat' => $bdLat,'lng' => $bdLon);
	}
	
	//BD-09 to GCJ-02
	public static function bd_decrypt($bdLat, $bdLng)
	{
	    $PI = 3.14159265358979324;
	    $x_pi = 0;
	    $x_pi = 3.14159265358979324 * 3000.0 / 180.0;
	    $x = $bdLng - 0.0065; $y = $bdLat - 0.006;
	    $z = sqrt($x * $x + $y * $y) - 0.00002 * sin($y * $x_pi);
	    $theta = atan2($y, $x) - 0.000003 * cos($x * $x_pi);
	    $gcjLon = $z * cos($theta);
	    $gcjLat = $z * sin($theta);
	    return array('lat' => $gcjLat, 'lng' => $gcjLon);
	}
	
}
